package jxau.jwgl.web.controller;

import jxau.jwgl.commons.WebData;
import jxau.jwgl.service.NotLoginException;
import jxau.jwgl.service.ServiceException;
import jxau.jwgl.web.utils.WebUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * ControllerExceptionHandler
 *
 * @author LongShu 2017/06/05
 */
@ControllerAdvice
public class ControllerExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(ControllerExceptionHandler.class);

    /**
     * Controller统一异常处理
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Object resolveException(HttpServletRequest request, HttpServletResponse response, Exception ex) {
        if (ex instanceof ServletRequestBindingException ||
                ex instanceof HttpMessageConversionException) {
            logger.warn("{}:{}", ex.getClass().getName(), ex.getMessage());
            return WebData.newError("参数错误!");
        } else if (ex instanceof NoHandlerFoundException) {
            return handlerError("请求的资源不存在!", 400, request, response);
        }

        logger.error(ex.getMessage(), ex);
        return handlerError("系统错误!", 500, request, response);
    }

    /**
     * 处理 ServiceException
     */
    @ExceptionHandler(ServiceException.class)
    @ResponseBody
    public Object resolveServiceException(HttpServletRequest request, HttpServletResponse response, Exception ex) {
        logger.warn(ex.getMessage());
        if (ex instanceof NotLoginException) {
            if (WebUtil.isAjax(request)) {
                return WebData.newError(ex.getMessage());
            }
            response.setStatus(HttpServletResponse.SC_OK);
            return new ModelAndView("user/login");
        }
        return handlerError(ex.getMessage(), 500, request, response);
    }

    private Object handlerError(String msg, int errorCode, HttpServletRequest request, HttpServletResponse response) {
        showUrl(request, errorCode);

        if (WebUtil.isAjax(request)) {
            return WebData.newError(msg);
        }
        response.setStatus(errorCode);
        ModelAndView mv = new ModelAndView("/error/" + errorCode);
        mv.setStatus(HttpStatus.valueOf(errorCode));
        mv.addObject("message", msg);
        return mv;
    }

    static void showUrl(HttpServletRequest request, int errorCode) {
        if (logger.isDebugEnabled()) {
            logger.debug("{}:{}?{} -> {}", request.getMethod(), request.getRequestURI(), request.getQueryString(), errorCode);
        }
    }

}
